package barinadroid.game;

import org.andengine.engine.handler.IUpdateHandler;
import org.andengine.entity.Entity;
import org.andengine.util.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;

public class ChaseAfterEntityBehavior extends Behavior implements IUpdateHandler
{
	private GameEntity chasedEntity;
	private final float STEP_DURATION = .52f;
	final float SPEED = 10f;
	private Vector2 maxVelocity;

	public static ChaseAfterEntityBehavior getNewBehavior(GameEntity chaser, GameEntity chased)
	{
		return new ChaseAfterEntityBehavior(chaser, chased);
	}

	/***
	 * Will calculate the multiplier between two points per axis. Usage: divide
	 * maxVelocity of an {@link Entity} or {@link GameEntity} with the result.
	 * 
	 * @param entityA
	 *            The chaser {@link Entity}.
	 * @param entityB
	 *            The chased {@link Entity}.
	 * @return A {@link Vector2} containing distance in percents from the bigger
	 *         distance.
	 */
	public static Vector2 RetrieveDistanceMultiplier(GameEntity entityA, GameEntity entityB)
	{
		Vector2 dis = new Vector2(), delta = new Vector2();
		// Retrieving distance per axis.
		dis.x = Math.abs(entityB.getCenter().x - entityA.getCenter().x);
		dis.y = Math.abs(entityB.getCenter().y - entityA.getCenter().y);
		if(dis.x > dis.y)// Detect which is smaller then calculate its percents
							// from the bigger distance
		{
			delta.x = 1;
			delta.y = dis.x / dis.y;
		}
		else
		{
			delta.y = 1;
			delta.x = dis.y / dis.x;
		}
		return delta;
	}

	public ChaseAfterEntityBehavior(final GameEntity chaser, final GameEntity chased)
	{
		super(chaser);
		this.chasedEntity = chased;
		getEntity().getBody().setType(BodyType.DynamicBody);
		// Vector2 position = calculateNewChaserPosition();
		// final MoveModifier chaseModifier = new MoveModifier(STEP_DURATION,
		// chaserCenterX(), position.x, chaserCenterY(), position.y);
		// chaseModifier.addModifierListener(new IModifierListener<IEntity>()
		// {
		// @Override
		// public void onModifierStarted(IModifier<IEntity> pModifier, IEntity
		// pItem)
		// {}
		//
		// @Override
		// public void onModifierFinished(IModifier<IEntity> pModifier, IEntity
		// pItem)
		// {
		// Vector2 position = calculateNewChaserPosition();
		// chaseModifier.reset(STEP_DURATION, chaserCenterX(), position.x,
		// chaserCenterY(), position.y);
		// }
		// });
		// super.registerEntityModifier(chaseModifier);
		this.maxVelocity = new Vector2(5, 5);
		super.registerUpdateHandler(this);
	}

	@SuppressWarnings("unused")
	@Deprecated
	private Vector2 calculateNewChaserPosition()
	{
		Vector2 position = new Vector2();
		float x1 = getChasedEntity().getCenter().x, y1 = getChasedEntity().getCenter().y, x2 = chaserCenterX(), y2 = chaserCenterY();
		float distance = MathUtils.distance(x1, y1, x2, y2);
		float d = distance - (distance - STEP_DURATION * SPEED);
		float m = (y1 - y2) - (x1 - x2);
		float c = (float)Math.sqrt(1 + m * m);
		position.x = x1 - (d / c);
		position.y = m * position.x - m * x1 + y1;
		position.x -= getChaserEntity().getSize().width * .5f;
		position.y -= getChaserEntity().getSize().height * .5f;
		return position;
	}

	public GameEntity getChaserEntity()
	{
		return getEntity();
	}

	public GameEntity getChasedEntity()
	{
		return this.chasedEntity;
	}

	private float chaserCenterX()
	{
		return getChaserEntity().getCenter().x;
	}

	private float chaserCenterY()
	{
		return getChaserEntity().getCenter().y;
	}

	@Override
	public void onUpdate(float pSecondsElapsed)
	{
		final float step = pSecondsElapsed * SPEED;
		Vector2 delta = RetrieveDistanceMultiplier(getChaserEntity(), getChasedEntity());
		Vector2 velocity = getChaserEntity().getBody().getLinearVelocity();
		if(chaserCenterX() > chasedEntity.getCenter().x)
		{// Within every case dividing by the Delta calculated above.
			if(velocity.x > -(maxVelocity.x / delta.x))
				velocity.x -= step;
		}
		else
		{
			if(velocity.x < maxVelocity.x / delta.x)
				velocity.x += step;
		}
		if(chaserCenterY() > chasedEntity.getCenter().y)
		{
			if(velocity.y > -(maxVelocity.y / delta.y))
				velocity.y -= step;
		}
		else
		{
			if(velocity.y < maxVelocity.y / delta.y)
				velocity.y += step;
		}
		getChaserEntity().getBody().setLinearVelocity(velocity);
	}

	@Override
	public void reset()
	{}
}